﻿using System;

namespace Ops.Mpc.ValidationServices.Attributes
{
    [AttributeUsage(AttributeTargets.Property)]
    public class RequiredStringAttribute : ValidationAttribute
    {
        #region Properties
        public int MinimumLength
        {
            get;
            set;
        }

        public int MaximumLength
        {
            get;
            set;
        }

        public int MinimumNumericCharacters
        {
            get;
            set;
        }

        public int MinimumAlphaCharacters
        {
            get;
            set;
        }

        public int MinimumUpperCaseCharacters
        {
            get;
            set;
        }

        public int MinimumLowerCaseCharacters
        {
            get;
            set;
        }

        public int MinimumPunctuationCharacters
        {
            get;
            set;
        }

        #endregion

        #region IValidationAttribute Members

        public override bool Validate(object container, object data, string[] propertyNames)
        {
            bool isValid = true;
            string value = data as string;

            if (!string.IsNullOrEmpty(value))
            {
                value = value.Trim();
                CharaterCount charaterCount = new CharaterCount(value);
                
                if (MinimumLength > 0)
                    isValid &= value.Length >= MinimumLength;
                if (MaximumLength > 0)
                    isValid &= value.Length <= MaximumLength;
                if (MinimumNumericCharacters > 0)
                    isValid &= charaterCount.NumberCharaters >= MinimumNumericCharacters;
                if (MinimumAlphaCharacters > 0)
                    isValid &= charaterCount.AlphaCharaters >= MinimumAlphaCharacters;
                if (MinimumUpperCaseCharacters > 0)
                    isValid &= charaterCount.UppperCaseCharaters >= MinimumUpperCaseCharacters;
                if (MinimumLowerCaseCharacters > 0)
                    isValid &= charaterCount.LowerCaseCharaters >= MinimumLowerCaseCharacters;
                if (MinimumPunctuationCharacters > 0)
                    isValid &= charaterCount.PunctuationCharaters >= MinimumPunctuationCharacters;


            }
            else
                isValid = false;

            return isValid;
        }

        public override string FormatMessage(string messageFormat, object container, object data, string name)
        {
            return string.Format(messageFormat,name, this.MinimumLength, this.MaximumLength,this.MinimumNumericCharacters,this.MinimumAlphaCharacters,this.MinimumUpperCaseCharacters,this.MinimumLowerCaseCharacters,this.MinimumPunctuationCharacters);
        }


        #endregion

        private class CharaterCount
        {
            public int NumberCharaters = 0;
            public int AlphaCharaters = 0;
            public int LowerCaseCharaters = 0;
            public int UppperCaseCharaters = 0;
            public int PunctuationCharaters = 0;

            public CharaterCount(string text)
            {

                foreach (char character in text)
                {
                    if (char.IsNumber(character))
                        this.NumberCharaters++;
                    else
                    {
                        this.AlphaCharaters++;

                        if (char.IsPunctuation(character))
                            this.PunctuationCharaters++;
                        else if (char.IsUpper(character))
                            this.UppperCaseCharaters++;
                        else
                            this.LowerCaseCharaters++;

                    }
                }

            }
        }
    }
}
